package edu.bmstu.rslab;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

/**
 * Created by Chikh (using IntelliJ IDEA).
 * Date: 14.04.2009
 * Time: 18:30:57
 */
public class VideoPanel extends JPanel {

    public VideoPanel(Camera camera) {
        this.camera = camera;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        if (!(isMagnification))
            video = camera.getImage();

        g2.setStroke(new BasicStroke(0.001f));
        double scaleX = (double) this.getWidth() / (double) video.getWidth(null);
        double scaleY = (double) this.getHeight() / (double) video.getHeight(null);
        if (scaleX < scaleY)
            scale = scaleX;
        else {
            scale = scaleY;
        }

        g2.scale(scale, scale);
        g2.drawImage(video, null, 0, 0);
        g2.setColor(Color.GREEN);
        for (Point2D point : basis) {
            Ellipse2D ellipse = new Ellipse2D.Double();
            ellipse.setFrameFromCenter(point.getX(), point.getY(),
                    point.getX()+2, point.getY()+2);
            g2.fill(ellipse);
        }
        g2.setColor(Color.BLUE);
        for (Point2D point : checkPoints) {
            Ellipse2D ellipse = new Ellipse2D.Double();
            ellipse.setFrameFromCenter(point.getX(), point.getY(),
                    point.getX()+2, point.getY()+2);
            g2.fill(ellipse);
        }

        g2.setColor(Color.GREEN);
        if (detectedPosition != null) {
            g2.draw(new Rectangle2D.Double(detectedPosition.getX() - 5, detectedPosition.getY() - 5, 10, 10));
        }
        g2.setColor(Color.darkGray);
        if (detectedDirection != null) {
            g2.draw(new Rectangle2D.Double(detectedDirection.getX() - 5, detectedDirection.getY() - 5, 10, 10));
        }
        if (selectingAreaPoint != null) {
            g2.setColor(Color.BLACK);
            Rectangle2D selectingRect = new Rectangle2D.Double();
            selectingRect.setFrameFromDiagonal(selectionCorner1, selectingAreaPoint);
            g2.draw(selectingRect);
            }
    }

    public void setCSBasis(ArrayList<Point2D> basis) {
        this.basis = basis;
        repaint();
    }

    public Point2D getScaledPoint(Point2D point) {
        return new Point2D.Double(point.getX()/scale, point.getY()/scale);
    }

    public void addToCheckPoints(Point2D point) {
        checkPoints.add(new Point2D.Double(point.getX()/scale, point.getY()/scale));
        repaint();
    }

    public void setDetectedPosition(Point2D position) {
        detectedPosition = position;
        repaint();
    }

    public void setDetectedDirection(Point2D position) {
        detectedDirection = position;
        repaint();
    }

    public void positionSet() {
        repaint();
    }


    public void beginSelecting(Point2D selectionCorner1) {
        this.selectionCorner1 = selectionCorner1;
    }

    public BufferedImage getSelectedMask(Point2D selectionCorner2) {
        selectingAreaPoint = null;
        Rectangle2D selectionRect = new Rectangle2D.Double();
        selectionRect.setFrameFromDiagonal(selectionCorner1, selectionCorner2);
        isMagnification = false;
        return video.getSubimage((int)Math.round(selectionRect.getX()), (int)Math.round(selectionRect.getY()),
                (int)Math.round(selectionRect.getWidth()),
                (int)Math.round(selectionRect.getHeight()));
    }

    public void selectingArea(Point2D selectingAreaPoint) {
        this.selectingAreaPoint = selectingAreaPoint;
        repaint();
    }

    public void showMagnifiedImage(Point2D selectionCorner2) {
        video = getSelectedMask(selectionCorner2);
        isMagnification = true;
        repaint();
    }

    double scale;
    private Camera camera;
    private ArrayList<Point2D> basis = new ArrayList<Point2D>();
    private ArrayList<Point2D> checkPoints = new ArrayList<Point2D>();
    private Point2D detectedPosition = null;
    private Point2D detectedDirection = null;
    private Point2D selectionCorner1 = null;
    private Point2D selectingAreaPoint = null;
    private boolean isMagnification = false;
    BufferedImage video;
}
